package com.fy.servlet.code;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;

/**
 * 验证码工具类（基类）
 * @author 小叶
 * @date 2016年5月20日
 * @version 3.0
 */
@WebServlet("/basecode.do")
public class BasicCode extends HttpServlet {
	private static final long serialVersionUID = 3L;
	protected static int CODE = 4; // 验证码个数
	protected static int LINE = 10; // 干扰线条数
	protected static int WIDTH = 24 * CODE; // 验证码宽度
	protected static int HEIGHT = 30; // 验证码高度
	@Override
	public void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); // 创建图像数据缓冲区
		Graphics g = image.getGraphics();// 创建图形变量
		g.setColor(BasicCode.getRandColor(180, 250)); // 设置画布的颜色
		g.fillRect(0, 0, WIDTH, HEIGHT); // 设置画布的尺寸
		BasicCode.drawLine(g, LINE, WIDTH, HEIGHT); // 随机生成干扰线
		String random = drawCode((Graphics2D) g); // 随机生成验证码
		req.getSession().setAttribute("checkcode", random); // 将随机码存在session中
		resp.setContentType("image/jpeg"); // 设置输出图片格式为JPEG
		// 设置报头控制浏览器不要缓存
		resp.setHeader("Pragma", "No-cache");
		resp.setHeader("Cache-Control", "no-cache");
		resp.setDateHeader("expries", 0);
		g.dispose(); // 使图像生效
		ImageIO.write(image, "jpeg", resp.getOutputStream()); // 输出绘制好的图片
	}
	/**
	 * 产生一个随机的颜色
	 * @param min 颜色分量最小值
	 * @param max 颜色分量最大值
	 * @return Color
	 */
	public static Color getRandColor(int min, int max) {
		Random random = new Random();
		if (min > 255)
			min = 255;
		if (max > 255)
			max = 255;
		int R = min + random.nextInt(max - min);
		int G = min + random.nextInt(max - min);
		int B = min + random.nextInt(max - min);
		return new Color(R, G, B);
	}
	/**
	 * 随机生成干扰线
	 * @param g 图形变量
	 * @param line 干扰线条数
	 * @param width 验证码宽度
	 * @param height 验证码高度
	 */
	public static void drawLine(Graphics g, int line, int width, int height) {
		Random rand = new Random();
		for (int i = 0; i < line; i++) {
			g.setColor(getRandColor(80, 160)); // 随机生成颜色
			g.drawLine(rand.nextInt(width), rand.nextInt(height), rand.nextInt(width), rand.nextInt(height)); // 随机绘制线条
			g.drawOval(rand.nextInt(width), rand.nextInt(height), 5, 5); // 随机绘制椭圆
		}
	}
	/**
	 * 随机生成验证码
	 * @param g 2D图形变量
	 * @return String 验证码
	 */
	public String drawCode(Graphics2D g) {
		Random rand = new Random(); // 创建随机数变量
		StringBuffer sb = new StringBuffer(); // 创建验证码存储变量
		g.setFont(new Font("Arial", Font.CENTER_BASELINE, 24)); // 设置验证码字体格式
		int x = 10, y = 20; // 设置绘制坐标
		String code = "Code"; // 自定义验证码
		for (int i = 0; i < CODE; i++) {
			String ch = String.valueOf(code.charAt(i)); // 从已定义的验证码中取字符
			sb.append(ch); // 添加到验证码存储变量
			int degree = rand.nextInt() % 30; // 设置字体旋转角度
			g.rotate(degree * Math.PI / 180, x, y); // 正向角度
			g.setColor(getRandColor(8, 80)); // 设置验证码颜色
			g.drawString(ch, x, y); // 绘制指定文本字符串
			g.rotate(-degree * Math.PI / 180, x, y); // 反向角度
			x += 20; // 设置间距
		}
		return sb.toString();
	}
}